const path = require("path");
const fs = require("fs");

class FilePak {
    prc = Promise.resolve();
    DataChunks = [];
    newTime = new Date().getTime();

    constructor(body, sign) {
        console.log('创建实例，分段总数:' + body.chunks)
        //储存文件分段信息
        this.info = body;
        this.dataLength = Number(body["chunks"]);
        this.size = body.size;
        this.id = body.id;
        this.filePath = path.join(body.upload_to, body.name); //储存文件路径
        this.chenkFilePath = this.filePath + '.scert';
        this.prc.then(()=>new Promise((resolve)=>{
            fs.createWriteStream(this.chenkFilePath).end(resolve);
        }));
        this.sign = sign;
    }

    addChunkData(file, i) {
        this.DataChunks[i] = file;
        i = Number(i);
        if (i < this.dataLength - 1) this.chunkSize = file.size;
         this.prc.then(() => this.pushFile(file, i));
        return this.isUpdata();
    }

    isUpdata() {
        for (let i = 0; i < this.dataLength; i++) {
            if (!this.DataChunks[i]) return false;
        }
        return true;
    }

    pushFile(file, chunk) {
        let start = chunk * this.chunkSize;
        let readStream = fs.createReadStream(file.path);
        let writeStream = fs.createWriteStream(this.chenkFilePath, {
            start: start,
            flags:'r+'
        });
        return new Promise((resolve, reject) => {
            readStream.pipe(writeStream);
            writeStream.on('finish', resolve);
            writeStream.on('error', reject);
        }).then(()=>{
            file.code = true;
            fs.unlink(file.path,(err)=>{
                if (err) console.error(err);
            })
            console.log('合并文件完成：'+chunk);
        }).catch((err) => {
            file.code = false;
            console.error('文件合并出错：\n' + err);
            throw new Error('文件合并出错:'+err);
        });
    }

    save() {
        return this.prc.then(() => {
            fs.renameSync(this.chenkFilePath, this.filePath);
            return this.filePath;
        })
    }

    delTmp() {
        for (let v of this.DataChunks) {
            if (v) {
                fs.unlinkSync(v.path);
            }
        }
        this.DataChunks = [];
        return true;
    }
}

module.exports = FilePak;